package 反射;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/*
测试暴力反射类:注意不需要main函数测试，也不需要新建对象，否则没意义
  Declared暴力获取对象类的getDeclaredField()私有属性
                             getDeclaredMethod()私有方法
暴力反射：只有newInstance()创建对象之后，才能进行【设置和获取】私有属性和私有方法
 */
public class TestReflect2 {
    @Test/*测试一：暴力获取Person类的私有属性*/
    public void  getField() throws Exception {
        Class<?> clazz = Class.forName("反射.Person");//1.获取字节码对象；类名指的是对象类+抛出异常；
        Field f = clazz.getDeclaredField("age");//指定参数:"变量名"。2.暴力获取私有属性可换为("name")
        System.out.println(f.getType().getName());//
        System.out.println(f.getType());//
        System.out.println(f.getName());//属性名
        //3.通过反射创建对象:newInstance()
        Object o = clazz.newInstance();
        System.out.println(o);//地址值
        //4.设置和获取属性之前，必须设置私有可见！！
        f.setAccessible(true);//f:私有属性变量
        f.set(o,18);//5.设置属性值:age--18  name---"小明"
        System.out.println(f.get(o));//6.获取属性值;18
    }


    @Test/*测试二、暴力反射获取Person类的私有方法*/
    public void getMethod() throws Exception {
        Class<?> clazz = Person.class;//1.获取字节码对象
        Method m = clazz.getDeclaredMethod("save",String.class,int.class);//say方法里面没有String和int
        //2：指定参数 暴力获取私有方法;参数列表（"方法名",基本类型.class）+抛出异常
        //3.通过反射创建对象
        Object o = clazz.newInstance();
        //4.设置私有可见
        m.setAccessible(true);
        //5.设置和获取私有方法 ----invoke:属于暴力反射
        m.invoke(o,"小莉",22);//(对象名，对应传参名);请保存一下小莉22
        System.out.println(o);
    }
}

